package pl.edu.pw.perg.compinfodb.datamodel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

import pl.edu.pw.perg.compinfodb.entities.ElementType;
import pl.edu.pw.perg.compinfodb.entities.VirtualElement;

public class PathTableModel implements TableModel, ChangeListener{

  private static final String FILTER_STRING = "Cable";
  private List<TableModelListener> listeners = new ArrayList<TableModelListener>();
  private List<ElementType> columns;
  private List<List<VirtualElement>> data;
  private boolean includeCables = true;
  private Map<Integer, Integer> filterMap = new HashMap<Integer, Integer>();
  
  public PathTableModel(List<List<VirtualElement>> data){
    this.data = data;
    if(data.size() == 0)
      return;
    List<VirtualElement> firstRow = data.get(0);
    for (VirtualElement virtualElement : firstRow) {
      ElementType type = virtualElement.getElementType(); 
      columns.add(type);
    }
    int j = 0;
    for (int i = 0; i < columns.size(); i++) {
      ElementType type = columns.get(i);
      if(!matchesFilter(type))
        filterMap.put(j++, i);
    }
  }
  
  public void addTableModelListener(TableModelListener l) {
    listeners.add(l);
  }

  public Class<?> getColumnClass(int columnIndex) {
    return null;
  }

  public int getColumnCount() {
    if(!includeCables)
      return filterMap.size();
    return columns.size();
  }

  public String getColumnName(int columnIndex) {
    if(includeCables)
      columnIndex = filterMap.get(columnIndex);
    return columns.get(columnIndex).getTypeName();
  }

  public int getRowCount() {
    return data.size();
  }

  public Object getValueAt(int rowIndex, int columnIndex) {
    if(includeCables)
      columnIndex = filterMap.get(columnIndex);
    return data.get(rowIndex).get(columnIndex);
  }

  public boolean isCellEditable(int rowIndex, int columnIndex) {
    return false;
  }

  public void removeTableModelListener(TableModelListener l) {
    listeners.remove(l);
  }

  public void setValueAt(Object value, int rowIndex, int columnIndex) {
    throw new UnsupportedOperationException("Path table not allows modification.");
  }

  private static boolean matchesFilter(ElementType type){
    return type.getTypeName().contains(FILTER_STRING)? true : false; 
  }

  public void stateChanged(ChangeEvent arg0) {
    includeCables = ((JCheckBox) arg0.getSource()).isSelected();
    for (TableModelListener l : listeners) {
      l.tableChanged(new TableModelEvent(this));
    }
  }
}
